#include <bits/stdc++.h>
using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

class MyLinkedList {
private:
    ListNode *head;
    ListNode *rear;
    int size;
public:
    MyLinkedList() {
        head = rear = NULL;
        size = 0;
    }
    
    int get(int index) {
        if(index <0 || index >=size) return -1;
        ListNode *p = head;
        while(index--){
            p = p->next;
        }
        return p->val;
    }
    
    void addAtHead(int val) {
        if(head == NULL){
            head = new ListNode(val, NULL);
            rear = head;
        }
        else {
            ListNode *new_head = new ListNode(val, head);
            head = new_head;
            ++size;
        }        
    }
    
    void addAtTail(int val) {
        if(rear == NULL) addAtHead(val);
        else {
            rear->next = new ListNode(val, NULL);
            rear = rear->next;
            ++size;
        }
    }
    
    void addAtIndex(int index, int val) {
        if(index <0 || index >size) return;
        if(index == 0) addAtHead(val);
        else if(index == size) addAtTail(val);
        else {
            ListNode *p = head;
            while(--index){
                p = p->next;
            }
            ListNode *new_node = new ListNode(val, p->next);
            p->next = new_node;
            ++size;
        }
    }
    
    void deleteAtIndex(int index) {
        if(index <0 || index >=size) return;
        if(index == 0){
            ListNode *deleteNode = head;
            head = head->next;
            delete deleteNode;
        }
        else {
            ListNode *p = head;
            while(--index){
                p = p->next;
            }
            ListNode *deleteNode = p->next;
            p->next = deleteNode->next;
            delete deleteNode;
        }
    }
};